﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fluq
{
	public sealed class DependencyContainer : IDependencyContainer
	{
		private IDependencyRegistry _registry;
		private IDependencyResolver _resolver;
		private IDependencyComposer _composer;
		private IDependencyLifetime _lifetime;

		public DependencyContainer(IDependencyRegistry registry, IDependencyResolver resolver, IDependencyComposer composer, IDependencyLifetime lifetime)
		{
			if (registry == null)
			{
				throw new ArgumentNullException("registry");
			}

			if (resolver == null)
			{
				throw new ArgumentNullException("resolver");
			}

			if (composer == null)
			{
				throw new ArgumentNullException("composer");
			}

			if (lifetime == null)
			{
				throw new ArgumentNullException("lifetime");
			}

			_registry = registry;
			_resolver = resolver;
			_composer = composer;
			_lifetime = lifetime;
		}

		public DependencyContainer()
			: this(DefaultRegistry(), DefaultResolver(), DefaultComposer(), DefaultLifetime())
		{

		}

		public static IDependencyContainer FromBuilder(IDependencyBuilder builder)
		{
			return new DependencyContainer(DecoratedRegistry(DependencyRegistry.FromBuilder(builder)), DefaultResolver(), DefaultComposer(), DefaultLifetime());
		}

		private static IDependencyRegistry DecoratedRegistry(IDependencyRegistry registry)
		{
			return new AutoDependencyRegistry(registry);
		}

		private static IDependencyRegistry DefaultRegistry()
		{
			return DecoratedRegistry(new DependencyRegistry());
		}

		private static IDependencyResolver DefaultResolver()
		{
			return new ListDependencyResolver(new FactoryDependencyResolver(new DependencyResolver()));
		}

		private static IDependencyComposer DefaultComposer()
		{
			return new PropertyDependencyComposer(new DependencyComposer());
		}

		private static IDependencyLifetime DefaultLifetime()
		{
			return new DependencyLifetime();
		}

		public IDependencyRegistry Registry { get { return _registry; } }

		public IDependencyResolver Resolver { get { return _resolver; } }

		public IDependencyComposer Composer { get { return _composer; } }

		public IDependencyLifetime Lifetime { get { return _lifetime; } }
	}
}
